#include <Ice/Application.h>
#include <FileTransfer.h>

using namespace std;
using namespace Ice;
using namespace FileTransfer;

class FileStoreI
  : public FileStore
{
public:
  FileStoreI();
  ~FileStoreI();
  virtual void read_async(const ::FileTransfer::AMD_FileStore_readPtr&, const ::std::string&, ::Ice::Int, ::Ice::Int, const ::Ice::Current&);
  void write(const ::std::string&, ::Ice::Int, const ::Ice::ByteSeq&, const ::Ice::Current&);
private:
  ::Ice::ByteSeq _bytes;
};

FileStoreI::FileStoreI()
{
}

FileStoreI::~FileStoreI()
{
}

void
FileStoreI::read_async(const ::FileTransfer::AMD_FileStore_readPtr& cb,
		       const ::std::string& name ,
		       ::Ice::Int offset,
		       ::Ice::Int num,
		       const ::Ice::Current&)
{

  FILE* fp = fopen(name.c_str(), "rb");

  if (fp == 0) {
    FileAccessException ex;
    ex.reason = "cannot open '" + name + "' for reading: " + strerror(errno);
    throw ex;
  }
  
  if (fseek(fp, offset, SEEK_SET) != 0) {
    fclose(fp);
    FileAccessException ex;
    ex.reason = "cannot open '" + name + "' for reading: " + strerror(errno);
    cb->ice_exception(ex);
  }

  Ice::ByteSeq bytes(num);
  ssize_t r = fread(&bytes[0], 1, num, fp);
  fclose(fp);
  pair<const Ice::Byte*, const Ice::Byte*> ret;
  ret.first = &bytes[0];
  ret.second = &bytes[r];

  cb->ice_response(ret);

}

void
FileStoreI::write(const ::std::string& name,
		  ::Ice::Int offset,
		  const ::Ice::ByteSeq& bytes,
		  const ::Ice::Current&)
{
}

class Server
  : virtual public Ice::Application
{
public:
  virtual int run (int argc,
		   char *argv[])
  {
    Ice::ObjectAdapterPtr adapter = communicator()->
      createObjectAdapterWithEndpoints("FileTransferAdapter", "tcp -h 161.67.38.113 -p 10000");
    Ice::ObjectPtr object = new FileStoreI;
    adapter->add(object, communicator()->stringToIdentity("FileStore"));
    adapter->activate();

    communicator()->waitForShutdown();
    return EXIT_SUCCESS;
  }
};

int main(int argc,
	 char* argv[])
{
  Server server;
  return server.main(argc, argv);
}
